/*
实现一个简单的 `axios` 主要涉及到以下几个核心功能：

1. **请求拦截器**：在发送请求之前对请求进行拦截和修改。
2. **响应拦截器**：在接收到响应之后对响应进行拦截和处理。
3. **Promise 风格的请求**：`axios` 基于 `Promise`，所以我们也要实现类似的机制。
4. **支持多种请求方式**：`get`, `post`, `put`, `delete` 等。

以下是一个简化版的 `axios` 实现：

### 1. 基础实现

```javascript
*/
class SimpleAxios {
    constructor() {
        this.interceptors = {
            request: [],
            response: []
        };
    }

    // 添加请求拦截器
    useRequestInterceptor(onFulfilled, onRejected) {
        this.interceptors.request.push({ onFulfilled, onRejected });
    }

    // 添加响应拦截器
    useResponseInterceptor(onFulfilled, onRejected) {
        this.interceptors.response.push({ onFulfilled, onRejected });
    }

    // 请求方法
    request(config) {
        // 拦截器链
        const chain = [
            { fulfilled: this.dispatchRequest, rejected: undefined },
            ...this.interceptors.request.reverse(),
            ...this.interceptors.response
        ];

        // 将请求包装成一个Promise链
        let promise = Promise.resolve(config);

        // 遍历拦截器链
        while (chain.length) {
            const { fulfilled, rejected } = chain.shift();
            promise = promise.then(fulfilled, rejected);
        }

        return promise;
    }

    // 实际发送请求的方法
    dispatchRequest(config) {
        return new Promise((resolve, reject) => {
            const { method = 'get', url, data } = config;
            const xhr = new XMLHttpRequest();

            xhr.open(method.toUpperCase(), url, true);
            xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');

            xhr.onload = () => {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve({
                        data: JSON.parse(xhr.responseText),
                        status: xhr.status,
                        statusText: xhr.statusText,
                        headers: xhr.getAllResponseHeaders(),
                        config
                    });
                } else {
                    reject(new Error(`Request failed with status code ${xhr.status}`));
                }
            };

            xhr.onerror = () => {
                reject(new Error('Network Error'));
            };

            xhr.ontimeout = () => {
                reject(new Error('Request timed out'));
            };

            xhr.send(data ? JSON.stringify(data) : null);
        });
    }

    // 各种请求方法
    get(url, config = {}) {
        return this.request({ ...config, method: 'get', url });
    }

    post(url, data, config = {}) {
        return this.request({ ...config, method: 'post', url, data });
    }

    // 其他 HTTP 方法可以类似实现：put, delete, etc.
}

// 创建一个 axios 实例
const axios = new SimpleAxios();

// 添加请求拦截器
axios.useRequestInterceptor(config => {
    console.log('Request Interceptor:', config);
    // 可以对 config 进行修改
    return config;
}, error => {
    return Promise.reject(error);
});

// 添加响应拦截器
axios.useResponseInterceptor(response => {
    console.log('Response Interceptor:', response);
    // 可以对响应进行处理
    return response;
}, error => {
    return Promise.reject(error);
});

// 使用 axios 发送请求
axios.get('https://jsonplaceholder.typicode.com/posts')
    .then(response => console.log('Response:', response))
    .catch(error => console.error('Error:', error));

/*
### 2. 代码解析

- **拦截器**：
  - `request` 和 `response` 拦截器分别存储在 `this.interceptors.request` 和 `this.interceptors.response` 数组中。
  - 在请求和响应过程中，拦截器按顺序执行。
  
- **请求方法**：
  - `request` 方法处理整个请求逻辑，包括应用拦截器和实际发送请求。
  - `dispatchRequest` 方法使用 `XMLHttpRequest` 来发送实际的 HTTP 请求。

- **HTTP 方法的实现**：
  - 实现了 `get` 和 `post` 请求，可以根据需要扩展其他方法如 `put`, `delete` 等。

### 3. 测试请求

上面的代码创建了一个 `axios` 实例，并添加了简单的请求和响应拦截器。你可以使用 `axios.get` 或 `axios.post` 等方法来发送 HTTP 请求。

这个简单的实现模拟了 `axios` 的大部分核心功能，包括拦截器、Promise 风格的请求、以及基本的 HTTP 方法。如果需要进一步扩展，还可以添加更多功能，如取消请求、超时处理、上传下载进度等。
*/

